Categories
JavaScript Best Practices

Better JavaScript — Higher-Order Functions and Call

Spread the love

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at ways to improve our JavaScript code.

Things we can do with Higher-Order Functions

We can do various things with higher-order functions.

They let us simplify the code that we repeat.

For instance, instead of writing a loop to loop through an array and push the entries to another array.

Instead of writing:

const names = ["foo", "bar", 'baz'];
const upper = [];
for (let i = 0; i <  names.length; i++) {
  upper[i] = names[i].toUpperCase();
}

We write use the map method to do the same thing:

const names = ["foo", "bar", 'baz'];
const upper = names.map((name) => name.toUpperCase());

We called map with a callback to return each entry as upper case.

It’s much shorter and simpler.

We can make our own higher-order function that takes a callback and do something by taking a callback function to make it do what we want.

For instance, we can write:

const buildString = (n, callback) => {
  let result = "";
  for (let i = 0; i < n; i++) {
    result += callback(Math.floor(Math.random() * 100) + i);
  }
  return result;
}

const str = buildString(8, String.fromCharCode);

We have created the buildString function that takes a callback function.

In the function, we created a for loop and call the callback with each iteration of the loop.

callback is is called with the character code to let us get the character.

And then we can call it by using passing in a number for the length and String.fromCharCode .

Then str is 'BO@B1&g’ .

Higher-order functions let us fix any bugs with just once since there’s no repeated code.

And there’s no code spread everywhere in our program.

Use call to Call Methods with a Custom Receiver

We can use the call method on a function to let us set the value of this and arguments we call with a function.

For instance, if we have:

f.call(obj, arg1, arg2, arg3);

Then that’s like calling:

f.call(arg1, arg2, arg3);

and setting this in f to obj .

The call method comes in handy for calling methods that may have been removed, modified or overridden.

For instance, the hasOwnProperty can be overridden by any object.

We can set:

obj.hasOwnProperty = 1;

Then if we write:

obj.hasOwnProperty("foo");

and we’ll get an error since hasOwnProperty has been set to 1.

The better to call hasOwnProperty is to use the call method.

For instance, we can write:

const dict = {};
dict.foo = 1;
delete dict.hasOwnProperty;
({}).hasOwnProperty.call(dict, "foo");

We created the dict object with the foo property.

And we deleted the hasOwnProperty property from dict .

Even if we did that, we can still call hasOwnProperty with an empty object by using the call method.

The first argument is the value of this in that we want to call hasOwnProperty with.

And the argument is the argument for hasOwnProperty .

Conclusion

Higher-order functions let us abstract out the logic into reusable pieces.

The call method lets us call a function with whatever value of this we want.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *